package org.point.common.util;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;

/**
 * <p> Title:时间工具类
 * <p> Description: 时间操作工具
 */
public final class DateTool
{
    /** 定义默认时间格式 yyyy-MM-dd hh:mm:ss ，例：2008-08-08 08:08:08 */
    public static final String DEFAULT_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    
    /** 定义默认日期格式 yyyy-MM-dd ，例：2008-08-08*/
    public static final String DEFAULT_DAY_FORMAT = "yyyy-MM-dd";
    
    /** 定义默认完整时间格式 yyyy-MM-dd hh:mm:ss.SSS ，例：2008-08-08 08:08:08.888 */
    public static final String DEFAULT_FULLTIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
    
    /** 定义类似流水号形式的时间格式 yyyyMMddhhmmss ，例：20080808080808 */
    public static final String DEFAULT_SERIAL_FORMAT = "yyyyMMddHHmmss";
    
    
    /** 定义fastDateFormat实例缓存区 */
    private static Map<String, FastDateFormat> fastDateFormatCache;
    
    static
    {
        // 初始化，缓存常见的几种时间格式

        fastDateFormatCache = new ConcurrentHashMap<String, FastDateFormat>();
        fastDateFormatCache.put(DEFAULT_TIME_FORMAT,
                FastDateFormat.getInstance(DEFAULT_TIME_FORMAT));
        fastDateFormatCache.put(DEFAULT_DAY_FORMAT,
                FastDateFormat.getInstance(DEFAULT_DAY_FORMAT));
        fastDateFormatCache.put(DEFAULT_FULLTIME_FORMAT,
                FastDateFormat.getInstance(DEFAULT_FULLTIME_FORMAT));
        fastDateFormatCache.put(DEFAULT_SERIAL_FORMAT,
                FastDateFormat.getInstance(DEFAULT_SERIAL_FORMAT));
        
    }
    
    /**
     * 私有构造函数，不允许实例化
     */
    private DateTool()
    {
    }
    
    /**
     * 将时间按照指定的时间格式转换成字符串
     * @param date 需要转换的date
     * @param format 时间格式
     * @return String 转换后的时间格式字符串，如果参数date为空，则返回null
     */
    public static String convertDate2String(Date date, String format)
    {
        if (null == date)
        {
            return null;
        }
        
        if (StringUtils.isEmpty(format))
        {
            // 如果传入的时间格式为空，则采用默认的时间格式
            format = DEFAULT_TIME_FORMAT;
        }
        
        // 从缓存区中查找

        FastDateFormat dateFormat = (FastDateFormat)fastDateFormatCache.get(format);
        // 如果查找不到，则生成指定格式的新实例，并添加到缓存区
        if (null == dateFormat)
        {
            dateFormat = FastDateFormat.getInstance(format);
            fastDateFormatCache.put(format, dateFormat);
        }
        
        return dateFormat.format(date);
    }
    
    /**
     * 获取指定格式的当前日期

     * @param pattern 日期格式，如:yyyyMMddhhmmss 
     * @return String 当前日期转换的的字符串

     */
    public static String getCurrentDate(String pattern)
    {
        if (StringUtils.isEmpty(pattern))
        {
            pattern = DEFAULT_TIME_FORMAT;
        }
        
        Date now = new Date();
        return convertDate2String(now, pattern);
    }
    
    /**
     * 获取当前日期
     * @return Date
     */
    public static Date getCurrentDate()
    {
        Date now = new Date();
        return now;
    }
    
    /**
     * 将字符串转换成日期 
     * @param timeStr 日期字符串

     * @param pattern 解析的格式

     * @return Date 转换后的日期
     */
    public static synchronized Date timeStr2Date(String timeStr, String pattern)
    {
        if (StringUtils.isEmpty(timeStr) ||StringUtils.isEmpty(pattern))
        {
            timeStr = "1700-01-01 00:00:00";
            pattern = DEFAULT_TIME_FORMAT;
        }
        SimpleDateFormat formatter = new SimpleDateFormat();
        formatter.applyPattern(pattern);
        try
        {
            return formatter.parse(timeStr);
        }
        catch (ParseException e)
        {
            
            throw new IllegalArgumentException(
                    new StringBuffer().append("using [")
                            .append(pattern)
                            .append("] parse [")
                            .append(timeStr)
                            .append("] failed")
                            .toString(), e);
        }
    }
    
    /**
     * 将日期型转换成字符串 
     * @param time 给定的日期

     * @param pattern 转换的目标格式

     * @return String 转换后的字符串

     */
    public static String date2TimeStr(Date time, String pattern)
    {
        if (time == null)
        {
            return null;
        }
        if (StringUtils.isEmpty(pattern))
        {
            pattern = DEFAULT_TIME_FORMAT;
        }
        return convertDate2String(time, pattern);
    }
    
    /**
     * 把时间转换成 yyyyMMddHHmm 格式
     * @param date date
     * @return String
     */
    public static String convertStrDate2(java.util.Date date)
    {
        if (date == null)
        {
            return null;
        }
        String pattern = "yyyyMMddHHmm";
        
        return convertDate2String(date, pattern);
    }
    
    /**
     * 取一天的开始时刻

     * @param date 给定的日期

     * @return Date 给定日期的开始时刻

     */
    public static Date getDateBeginTime(Date date)
    {
        String beginTime = convertDate2String(date, "yyyy-MM-dd 00:00:00");
        return timeStr2Date(beginTime, DEFAULT_TIME_FORMAT);
    }
    
    /**
     * 取一天的结束时刻
     * @param date 给定的日期

     * @return Date 给定日期的结束时刻

     */
    public static Date getDateEndTime(Date date)
    {
        String beginTime = convertDate2String(date, "yyyy-MM-dd 23:59:59");
        return timeStr2Date(beginTime, DEFAULT_TIME_FORMAT);
    }
    
    /**
     * 某个日期增加几个月后的日期

     * @param date 指定的日期

     * @param monthNum 需要增加的月数
     * @return Date 增加后的日期
     */
    public static Date addMonths(Date date, int monthNum)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, monthNum);
        return cal.getTime();
    }
    
    /**
     * 某个日期增加 多少分钟后的日期
     * @param date
     * @param minutes
     * @return
     */
    public static Date addMinutes(Date date, int minutes)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MINUTE, minutes);
        return cal.getTime();
    }
    
    /**
     * 转换时间格式字符串

     * @param date 需要转换的时间格式字符串

     * @return 转换后的时间格式字符串

     */
    public static String formatStrDate(String date)
    {
        Date d = timeStr2Date(date, DEFAULT_TIME_FORMAT);
        return convertDate2String(d, DEFAULT_SERIAL_FORMAT);
    }
    
    /**
     * 转换时间格式字符串
     * @param date 需要转换的时间格式字符串
     * @param fmt1 转换前的格式
     * @param fmt2 转换后的格式
     * @return 转换后的时间格式字符串
     */
    public static String formatStrDate(String date, String fmt1, String fmt2){
        Date d = timeStr2Date(date, fmt1);
        return convertDate2String(d, fmt2);
    }
    
    /**
     * 校验时间的格式

     * @param data 需要校验的时间字符串

     * @return boolean 是否匹配
     */
    public static boolean checkDate(String data)
    {
        String regex = "^(19)|(20)\\d{2}[-\\s]((0)\\d|(1)[0-2]{1})[-\\s]([0-2]{1}\\d|(3)[0-1]{1})[ \\s]([0-1]{1}\\d|(2)[0-3]{1})[:\\s][0-5]{1}\\d[:\\s][0-5]{1}\\d.*";
        return data.matches(regex);
    }
    
    public static void main(String[] args) {
        String ss = formatStrDate("20130521000000","yyyyMMddHHmmss","yyyy-MM-dd HH:mm:ss");
        System.out.println(ss);
    }
}
